<?php

/**
 * 
 * @author arlonzou
 *
 */
require_once 'json.class.php';
class IwenwenApi{
	var $discuzid;
	var $appkey;
	var $secretkey;
	var $last_ret; // 上次post接口调用返回的内容。
	function IwenwenApi() {
		global $_G;
		$this->discuzid = $_G['setting']['my_siteid'];
		$this->appkey = $_G['setting']['iwenwen_appkey'];
		$this->secretkey = $_G['setting']['iwenwen_secretkey'];
	}
	
	function getLastReturn(){
		return $this->last_ret;
	}

    function postMessageWithJson($json) {
        $param = $this->generateSiteSignParam(array('did'=>$this->discuzid));
        $url = 'http://open.wenwen.soso.com/z/openapi/discuz/submitcontent?'.$param;
        $start = time();
        try {
            $apiresult = $this->_dfsimplejsonpost($url, $json, 2);
            $result = CJSON::decode($apiresult);
        } catch (Exception $exp) {
            $result = false;
        }
        $end = time();
        $serinfo = $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
        //$log = (empty($result) ? 'false' : join('||', $result)) . ' ' . ($end - $start) . ' ' . $url . ' ' . $serinfo . ' ' . str_replace('\n', '_', str_replace('\r\n', '_', $json));
        //$logfile = DISCUZ_ROOT . './data/log/iwenwen_sync.log';
        //file_put_contents($logfile, $log . PHP_EOL, FILE_APPEND);
    }

	function getCategories(){
		$param = $this->generateSiteSignParam();
		$url = 'http://open.wenwen.soso.com/z/openapi/get?id=275&type=2&'.$param;
		do{
			$result = dfsockopen($url);
			$i++;
    	}while(empty($result) && $i<3);
    	return $result;
	}
	function applyIwenwenAppInfo($posts){
		$url = 'http://open.wenwen.soso.com/z/openapi/discuz/applyapp';
		$result = $this->_dfsockopen($url,0,$posts,'',FALSE,'',15,TRUE,'MULTIPART',false);
		return CJSON::decode($result);
		
	}
	
	function getIwenwenAppInfo(){
		$param = $this->generateSiteSignParam(array('did'=>$this->discuzid));
		$url = 'http://open.wenwen.soso.com/z/openapi/discuz/getapp?'.$param;
		$ret = $this->post($url,0,$posts,'',FALSE,'',15,TRUE,'URLENCODE',false);
		return $ret;
	}
	
	function editIwenwenAppInfo($posts){
		$param = $this->generateSiteSignParam(array('did'=>$this->discuzid));
		$url = 'http://open.wenwen.soso.com/z/openapi/discuz/modifyapp?'.$param;
		$result = $this->_dfsockopen($url,0,$posts,'',FALSE,'',15,TRUE,'MULTIPART',false);
		return CJSON::decode($result);
	}
	
	function checkIwenwenStatus(){
		$url = 'http://open.wenwen.soso.com/z/openapi/discuz/getStatus?discuzid='.$this->discuzid;
		return $this->post($url);
	}
	
	function setStatus($status = array()){
		$param = $this->generateSiteSignParam();
		$url = 'http://open.wenwen.soso.com/z/openapi/discuz/updateStatus?'.$param;
		return $this->post($url,$status);
	}
	
	/**
	 * 检查输入的appkey，secretkey是否正确
	 * @param unknown_type $appkey
	 * @param unknown_type $secretkey
	 * @return Ambigous <boolean, NULL, number, multitype:, mixed, stdClass, string, multitype:Ambigous <mixed, boolean, NULL, number, string, multitype:, stdClass> >
	 */
	function checkAppSecret($appkey,$secretkey){
		$this->appkey = $appkey;
		$this->secretkey = $secretkey;
		$param = $this->generateSiteSignParam(array('discuzid'=>$this->discuzid));
		$url = 'http://open.wenwen.soso.com/z/openapi/discuz/verifykey?'.$param;
		return $this->post($url);
	}
	
	/**
	* 被删除的回流数据，上报给开放平台
	*/
	function deletewenwen($qid,$answerid=0){
		$param = $this->generateSiteSignParam();
		$url = 'http://open.wenwen.soso.com/z/openapi/discuz/dzdel?'.$param;
		$posts = array('qid' => $qid,'answerId' => $answerid);
		return $this->post($url,$posts);
	}
	/**
	 * 通过接口发表问题
	 * @param unknown_type $posts
	 * @return array
	 */
	function sendNewQuestion($posts){
		$url = 'http://open.wenwen.soso.com/z/openapi/ask?'.$this->generateSiteSignParam();
		return $this->post_json($url,$posts);
	}
	
	/**
	 * 通过接口对问题进行回答
	 * @param unknown_type $posts
	 * @return array
	 */
	function sendNewAnswer($posts){
		$url = 'http://open.wenwen.soso.com/z/openapi/answer?'.$this->generateSiteSignParam();
		return $this->post_json($url,$posts);
	}
	
	/**
	 * 回帖问题
	 */
	function sendPostAccount(){
		$curr_date = date('Ymd',strtotime('-1 day'));
		$coutinfo = $hasone = DB::fetch_first("select * from ".DB::table('iwenwen_answers')." where `date`='".$curr_date."'",null,true);
		if(!empty($coutinfo)){
			$param = $this->generateSiteSignParam();
			$url = 'http://open.wenwen.soso.com/z/openapi/discuz/ancount?'.$param;
			return $this->post($url,array('date'=> date('Y-m-d',strtotime('-1 day')),'count'=> $coutinfo['post_num']));
		}
		return false;
	}
	
	function  getIwenwenForums(){
		global $_G;
		// 加载Forum缓存
		require_once libfile('function/forumlist');		
		if(!isset($_G['cache']['forums'])){
			loadcache('forums');
		}
		$forumcache = &$_G['cache']['forums'];		
		
		if(empty($_G['setting']['iwenwen_question_forums_keyword'])){
			loadcache('setting');
		}
		if(empty($_G['setting']['iwenwen_question_forums_keyword'])){
			require_once libfile('function/cache');
			updatecache(array('setting')); // 若为空，则更新缓存
		}
		$selectedfid = explode(',',$_G['setting']['iwenwen_question_forums']);	
		$selectedfid = array_filter($selectedfid);		
		$keywords = unserialize($_G['setting']['iwenwen_question_forums_keyword']);
		if(!is_array($keywords)){
			$keywords = array();	
		}
		
		$iwenwen_forums = array();
		foreach($forumcache as $forum){
			if(!$forum['status']){
				continue;
			}
			
			if(empty($selectedfid) || in_array($forum['fid'],$selectedfid)){
				if(empty($keywords[$forum['fid']]['keyword'])){
					$iwenwen_forums[] = array(
						'id' => intval($forum['fid']),
						'name' => $forum['name'],
						'status' => 1,
						'keyword' => ''
					);
				}
				else{
					$keywords[$forum['fid']]['keyword'] = array_filter($keywords[$forum['fid']]['keyword']);
					$iwenwen_forums[] = array(
						'id' => intval($forum['fid']),
						'name' => $forum['name'],
						'status' => 1,
						'keyword' => implode('#',$keywords[$forum['fid']]['keyword'])
					);
				}
			}
			else{
				$iwenwen_forums[] = array('id'=>intval($forum['fid']),'name'=>$forum['name'],'status'=>0,'keyword' => '');
			}
		}
		return $iwenwen_forums;
	}
	
	/**
	 * 若版面发生变化(新增或删除了版面)，将版面信息推送至问问开放平台
	 * @param $forse 是否强制同步，false时，默认24小时传一次版面，时间间隔未到时，忽略调用
	 */
	function updateCategory($forse=false){
		global $_G;
		
		if(!$forse && TIMESTAMP-$_G['setting']['iwenwen_last_sync'] < 43200)
		{
			return true; // not in time interval ,skip.
		}
		$iwenwen_forums = $this->getIwenwenForums();
		$iwenwen_forums['forbid_words'] = implode('#',explode("\n",$_G['setting']['iwenwen_unbackflow_words']));
		$forums = CJSON::encode($iwenwen_forums);
		// send to wenwen whether change or not
		DB::query("REPLACE INTO ".DB::table('common_setting')." (`skey`, `svalue`) VALUES ('iwenwen_last_sync','".TIMESTAMP."')");
		require_once libfile('function/cache');
		updatecache(array('setting'));
		
		$param = $this->generateSiteSignParam();
		$url = 'http://open.wenwen.soso.com/z/openapi/discuz/updateCategory?'.$param;
		return $this->post($url,array('type'=> 1,'categorys'=> $forums,'forbid_words' => $iwenwen_forums['forbid_words']));
	}
	/**
	 * 请求指定url的内容,已json格式提交
	 * 无法获取内容时，重试3次
	 * @param string $url
	 * @param array $posts 数组，自动追加参数discuzid
	 */
	function post_json($url,$posts=array()){
		//print_r($posts);
		if(is_array($posts) && !empty($posts)){
			$i=0;
			do{
				$posts['discuzid'] = $this->discuzid;
				$posts['format'] = 'json';
				$posts_str = CJSON::encode($posts);
				$result = $this->_dfsockopen($url, 0, $posts_str,'',false,'',15,true,'JSONENCODE',false);				
				$i++;
			}while(empty($result) && $i<3);
			$this->last_ret = $result;
			return CJSON::decode($result);
		}
		else{
			return array('msg'=>'posts need as array.');
		}
	}
	
	var $boundary = '---------------------------19761103198182';
	
	function getPostBoundryContent($post,$files){
		$data = '';
		//拼接Post
	    foreach ($post AS $index => $value) {
	        $data .="--".$this->boundary."\r\n";
	        $data .= "Content-Disposition: form-data; name=\"" . $index . "\"\r\n";
	        $data .= "\r\n" . $value . "\r\n";
	    }
	     
	    //拼接要上传的文件
	    foreach ($files as $k => $file) {
	    	//Content-Disposition: form-data; name="logo1"; filename="Chrysanthemum.jpg"
	    	//Content-Type: image/jpeg
	        $content_file = file_get_contents($file['tmp_name']);
	        $data .= "--".$this->boundary."\r\n";
	        $data .="Content-Disposition: form-data; name=\"{$k}\"; filename=\"{$file['name']}\"\r\n";
	        $data .= "Content-Type: {$file['type']}\r\n\r\n";
	        $data .= "" . $content_file . "\r\n";
	    }
	    $data .="--".$this->boundary."--\r\n";
	    return $data;
	}
	/**
	 * 请求指定url的内容
	 * 无法获取内容时，重试3次
	 * @param string $url
	 * @param array $posts 数组，自动追加参数discuzid
	 */
	function post($url,$posts=array()){
        //print_r($posts);
    	$i=0;
    	do{
				if(is_array($posts) && !empty($posts)){
					$posts['discuzid'] = $this->discuzid;
					$posts = $this->httpBuildQuery($posts);
					$result = $this->_dfsockopen($url, 0, $posts,'',false,'',15,true,'URLENCODE');		
				}
				else{
					$result = dfsockopen($url);
				}
				$i++;
    	}while(empty($result) && $i<3);
    	$this->last_ret = $result;
		return CJSON::decode($result);
	}
	
	/**
	* 生成校验的get参数
	*/
	function generateSiteSignParam($params = array(), $isCamelCase = false) {
		
		if(!is_array($params)) {
			$params = array();
		}
		#$params['discuzid'] = $this->discuzid;
		$params['appkey'] = $this->appkey;
		$params['timestamp'] = time().'000';		
		unset($params['sign']);
		ksort($params);
	
		$str = $this->httpBuildQuery($params, '', '&');
		$sign = md5(sprintf('%s%s', $str, $this->secretkey));
				
		$params['sign'] = $sign;	
		$url = $this->httpBuildQuery($params, '', '&');
		return $url;
	}
	
	function httpBuildQuery($data, $numeric_prefix='', $arg_separator='', $prefix='') {
	
		$render = array();
		if (empty($arg_separator)) {
			$arg_separator = @ini_get('arg_separator.output');
			empty($arg_separator) && $arg_separator = '&';
		}
		foreach ((array) $data as $key => $val) {
			if (is_array($val) || is_object($val)) {
				$_key = empty($prefix) ? "{$key}[%s]" : sprintf($prefix, $key) . "[%s]";
				$_render = $this->httpBuildQuery($val, '', $arg_separator, $_key);
				if (!empty($_render)) {
					$render[] = $_render;
				}
			} else {
				if (is_numeric($key) && empty($prefix)) {
					$render[] = urlencode("{$numeric_prefix}{$key}") . "=" . urlencode($val);
				} else {
					if (!empty($prefix)) {
						$_key = sprintf($prefix, $key);
						$render[] = urlencode($_key) . "=" . urlencode($val);
					} else {
						$render[] = urlencode($key) . "=" . urlencode($val);
					}
				}
			}
		}
		$render = implode($arg_separator, $render);
		if (empty($render)) {
			$render = '';
		}
	
		return $render;
	}

    function _dfsimplejsonpost($url, $post, $timeout) {
        return $this->_dfsockopen($url, 0, $post, '', FALSE, '', $timeout, TRUE, 'JSONENCODE', FALSE);
    }
	
	function _dfsockopen($url, $limit = 0, $post = '', $cookie = '', $bysocket = FALSE, $ip = '', $timeout = 15, $block = TRUE, $encodetype  = 'URLENCODE', $allowcurl = TRUE) {
		$return = '';
		$matches = parse_url($url);
		$scheme = $matches['scheme'];
		$host = $matches['host'];
		$path = $matches['path'] ? $matches['path'].($matches['query'] ? '?'.$matches['query'] : '') : '/';
		$port = !empty($matches['port']) ? $matches['port'] : 80;
	
		if(function_exists('curl_init') && function_exists('curl_exec') && $allowcurl) {
			$ch = curl_init();
			$ip && curl_setopt($ch, CURLOPT_HTTPHEADER, array("Host: ".$host));
			curl_setopt($ch, CURLOPT_URL, $scheme.'://'.($ip ? $ip : $host).':'.$port.$path);
			curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
			if($post) {
				curl_setopt($ch, CURLOPT_POST, 1);
				if($encodetype == 'URLENCODE' || $encodetype== 'JSONENCODE') {
					curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
				} else {
					parse_str($post, $postarray);
					curl_setopt($ch, CURLOPT_POSTFIELDS, $postarray);
				}
			}
			if($cookie) {
				curl_setopt($ch, CURLOPT_COOKIE, $cookie);
			}
			curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
			curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
			$data = curl_exec($ch);
			$status = curl_getinfo($ch);
			$errno = curl_errno($ch);
			curl_close($ch);
			if($errno || $status['http_code'] != 200) {
				return;
			} else {
				return !$limit ? $data : substr($data, 0, $limit);
			}
		}
	
		if($post) {
			$out = "POST $path HTTP/1.0\r\n";
			$header = "Accept: */*\r\n";
			$header .= "Accept-Language: zh-cn\r\n";
			$boundary = ($encodetype == 'URLENCODE' || $encodetype == 'JSONENCODE') ? '' : '; boundary='.$this->boundary;
			$header .= $encodetype == 'JSONENCODE' ? "Content-Type: application/json;charset=utf8\r\n" : ($encodetype == 'URLENCODE' ? "Content-Type: application/x-www-form-urlencoded\r\n" : "Content-Type: multipart/form-data$boundary\r\n");
			$header .= "User-Agent: $_SERVER[HTTP_USER_AGENT]\r\n";
			$header .= "Host: $host:$port\r\n";
			$header .= 'Content-Length: '.strlen($post)."\r\n";
			$header .= "Connection: Close\r\n";
			$header .= "Cache-Control: no-cache\r\n";
			$header .= "Cookie: $cookie\r\n\r\n";
			$out .= $header.$post;
		} else {
			$out = "GET $path HTTP/1.0\r\n";
			$header = "Accept: */*\r\n";
			$header .= "Accept-Language: zh-cn\r\n";
			$header .= "User-Agent: $_SERVER[HTTP_USER_AGENT]\r\n";
			$header .= "Host: $host:$port\r\n";
			$header .= "Connection: Close\r\n";
			$header .= "Cookie: $cookie\r\n\r\n";
			$out .= $header;
		}
	
		$fpflag = 0;
		if(!$fp = @fsocketopen(($ip ? $ip : $host), $port, $errno, $errstr, $timeout)) {
			$context = array(
					'http' => array(
							'method' => $post ? 'POST' : 'GET',
							'header' => $header,
							'content' => $post,
							'timeout' => $timeout,
					),
			);
			$context = stream_context_create($context);
			$fp = @fopen($scheme.'://'.($ip ? $ip : $host).':'.$port.$path, 'b', false, $context);
			$fpflag = 1;
		}
	
		if(!$fp) {
			return '';
		} else {
			stream_set_blocking($fp, $block);
			stream_set_timeout($fp, $timeout);
			@fwrite($fp, $out);
			$status = stream_get_meta_data($fp);
			if(!$status['timed_out']) {
				while (!feof($fp) && !$fpflag) {
					if(($header = @fgets($fp)) && ($header == "\r\n" ||  $header == "\n")) {
						break;
					}
				}
	
				$stop = false;
				while(!feof($fp) && !$stop) {
					$data = fread($fp, ($limit == 0 || $limit > 8192 ? 8192 : $limit));
					$return .= $data;
					if($limit) {
						$limit -= strlen($data);
						$stop = $limit <= 0;
					}
				}
			}
			@fclose($fp);
			return $return;
		}
	}
}
